package com.bluesky.plum.uimodels.standard.components.objectBrowser;

import java.util.ArrayList;
import java.util.List;

import com.bluesky.plum.domain.repository.Repository;
import com.bluesky.plum.domain.repository.RepositoryFactory;
import com.bluesky.plum.richdomain.FieldType;
import com.bluesky.plum.richdomain.RichDomainField;
import com.bluesky.plum.uimodels.standard.FieldUIComponent;
import com.bluesky.plum.uimodels.standard.StandardUIComponentType;
import com.bluesky.plum.uimodels.standard.UIComponent;
import com.bluesky.plum.uimodels.standard.UIComponentBuilder;
import com.bluesky.plum.uimodels.standard.components.EventListener;
import com.bluesky.plum.uimodels.standard.components.listbox.SelectionMode;
import com.bluesky.plum.uimodels.standard.components.listbox.Selector;

/*
 * it is as simple as a list box
 */
public class ObjectSelector<T extends Object> extends FieldUIComponent  {
	protected Selector selector;

	protected List options;

	protected Repository<T> repo;
	protected SelectionMode selectionMode;

	private EventListener selectionChangeListener;

	public ObjectSelector(RichDomainField field) {
		super(field);

		// if (field.fieldType == FieldType.ObjectReference)
		// setSelectionMode(SelectionMode.Single);
		// else
		// setSelectionMode(SelectionMode.Multiple);

		//setObjectRepository(RepositoryFactory.getRepository(field.fieldClass))
		// ;
	}

	@Override
	public void setUiComponentBuilder(UIComponentBuilder uiComponentBuilder) {

		super.setUiComponentBuilder(uiComponentBuilder);

		selector = (Selector) uiComponentBuilder
				.createNonFieldComponent(StandardUIComponentType.ListBox);
		UIComponent selectionComponent =(UIComponent)selector;
		selectionComponent.setName(getField().name);

		if (field.fieldType == FieldType.ObjectReference) {
			setSelectionMode(SelectionMode.Single);
			setObjectRepository(RepositoryFactory
					.getRepository(field.fieldClass));
		} else {
			setSelectionMode(SelectionMode.Multiple);
			setObjectRepository(RepositoryFactory
					.getRepository(field.elementClass));
		}

		setDomainFieldValue(field.value);
		selector.setSelectChangeListener(new EventListener() {
			@Override
			public void process() {
				if (getSelectionChangeListener() != null)
					getSelectionChangeListener().process();
				
				if (getValueChangeEventListener() != null)
					getValueChangeEventListener().process();

			}
		});
		
		addChildComponent(selectionComponent);
	}

	
	public void setObjectRepository(Repository<T> repo) {
		this.repo = repo;

		selector.setObjects(repo.getAll());
		selector.setObjectEqualor(new Selector.ObjectEqualor(){
			@Override
			public boolean equals(Object obj1, Object obj2) {
				
				return getRepo().equals((T)obj1, (T)obj2);
			}
		});
	}

	
	public void setSelectionMode(SelectionMode mode) {
		this.selectionMode = mode;
		
		selector.setSelectionMode(mode);

	}

	public SelectionMode getSelectionMode() {
		return selectionMode;
	}



	public Repository<T> getRepo() {
		return repo;
	}

	public void setRepo(Repository<T> repo) {
		this.repo = repo;
	}

	public EventListener getSelectionChangeListener() {
		return selectionChangeListener;
	}

	public void setSelectionChangeListener(EventListener selectionChangeListener) {
		this.selectionChangeListener = selectionChangeListener;
	}

	@Override
	public Object getDomainFieldValue() {

		if (selectionMode == SelectionMode.Single)
			return selector.getSelectedValue();
		else if (selectionMode == SelectionMode.Multiple){
			Object[] values=selector.getSelectedValues();
			List list = new ArrayList();
			
			for(Object o : values)
				list.add(o);
			
			return list; 
		}
		else
			throw new RuntimeException("selectionMode is null");

	}

	@Override
	public void setDomainFieldValue(Object value) {
		if (value == null)
			return;

		if (selectionMode == SelectionMode.Single)
			selector.setSelectedValue(value);
		else{
			List list = (List)value;
			
			selector.setSelectedValues(list.toArray());
			
		}
	}

	@Override
	public Object getNativeComponent() {

		return ((UIComponent) selector).getNativeComponent();
	}
}
